#include<stdio.h>
#include "GrammaAnalyse.h"
#include "lexer.hpp"
#include <sstream>

LR1Table table;
Lexer lexer;
string lexer_output_file = "build/lex.tsv";
string gramma_output_file = "build/gra.tsv";

void init()
{
	lexer.init(lexer_output_file);
	table.init("build/table.txt", gramma_output_file);
	table.reset();
}

int main(int argc, char** argv)
{
	system("chcp 65001");
	init();
//    cout<<SELECT<<root<<endl;
	string s; // 词法分析结果
	lexer.run("doc/test.txt");
	bool contains = false;
	while(lexer.next(true))
	{
		contains = false;
		// 词法分析
		Token token = lexer.get_token();
		s.assign(token.type);
		//语法分析
		element_t ele = parseString(s);
		if(!table.parseToken(ele))
		{
			cout << "语法分析错误," << "错误符号: " << terminal_symbol_t_tostring(ele.terminal) << " " << (token.str.has_value() ? token.str.value() : "") << endl;
			if(token.type != "VAREPSILON")
			{
				while(lexer.next(true))
				{
					token = lexer.get_token();
					if(token.type == "VAREPSILON")
						break;
				}

			}
			table.reset();
		}
		else if(ele.terminal == VAREPSILON)
		{
			contains = true;
			cout << "归约成功" << endl;
			table.reset();
		}
	}
	if(!contains)
	{
		element_t ele;
		ele.type = 0;
		ele.value = VAREPSILON;
		if(!table.parseToken(ele))
		{
			cout << "语法分析错误," << "错误符号: " << terminal_symbol_t_tostring(ele.terminal) << endl;
		}
		else
		{
			cout << "归约成功" << endl;
		}
	}

#ifdef LEXER
    // 对词法分析器进行初始化
	Lexer lexer;
    lexer.init();
    FILE* file = fopen("examples/test0B.txt", "r");
    if(file){
        char* buf = new char[512];
        fread(buf, 1, 512, file);
        lexer.run(buf);
		while(lexer.next(true));
    }
#endif

#ifdef DFA
		NFAToDFA nfa_to_dfa = NFAToDFA("examples/dfa_test.txt");
		nfa_to_dfa.nfa_determine();
		nfa_to_dfa.print_dfa_final_state();
		std::cout<<"DFA Determinate: \n";
		nfa_to_dfa.print_dfa_table();
		std::cout<< "\n";
		std::vector<std::vector<int>> dfa = nfa_to_dfa.dfa_minialize();
		std::cout<< "DFA Minialize: \n";
		for(size_t i = 0; i < dfa.size(); i++) {
			std::vector<int> child = dfa[i];
			std::cout<<"State "<<i << ": ";
			std::cout<< "{";
			for(size_t j = 0; j < child.size(); j++) {
				std::cout<< child[j] << " ";
			}
			std::cout<<"}";
			std::cout<<"\n";
		}
		std::cout<<"\n";
		return 0;
#endif

	return 0;


}